附录B. 配置元数据

Spring Boot jars包含元数据文件,它们提供了所有支持的配置属性详情。这些文件设计用于让IDE开发者能够为使用application.propertiesapplication.yml文件的用户提供上下文帮助及代码完成功能。

主要的元数据文件是在编译器通过处理所有被@ConfigurationProperties注解的节点来自动生成的。

附录B.1. 元数据格式

配置元数据位于jars文件中的META-INF/spring-configuration-metadata.json,它们使用一个具有"groups"或"properties"分类节点的简单JSON格式:

{"groups": [
    {
        "name": "server",
        "type": "org.springframework.boot.autoconfigure.web.ServerProperties",
        "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
    },
    {
        "name": "spring.jpa.hibernate",
        "type": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate",
        "sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties",
        "sourceMethod": "getHibernate()"
    }
    ...
],"properties": [
    {
        "name": "server.port",
        "type": "java.lang.Integer",
        "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
    },
    {
        "name": "server.servlet-path",
        "type": "java.lang.String",
        "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties",
        "defaultValue": "/"
    },
    {
          "name": "spring.jpa.hibernate.ddl-auto",
          "type": "java.lang.String",
          "description": "DDL mode. This is actually a shortcut for the \"hibernate.hbm2ddl.auto\" property.",
          "sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate"
    }
    ...
],"hints": [
    {
        "name": "spring.jpa.hibernate.ddl-auto",
        "values": [
            {
                "value": "none",
                "description": "Disable DDL handling."
            },
            {
                "value": "validate",
                "description": "Validate the schema, make no changes to the database."
            },
            {
                "value": "update",
                "description": "Update the schema if necessary."
            },
            {
                "value": "create",
                "description": "Create the schema and destroy previous data."
            },
            {
                "value": "create-drop",
                "description": "Create and then destroy the schema at the end of the session."
            }
        ]
    }
]}

每个"property"是一个配置节点,用户可以使用特定的值指定它。例如,server.portserver.servlet-path可能在application.properties中如以下定义:

server.port=9090
server.servlet-path=/home

"groups"是高级别的节点,它们本身不指定一个值,但为properties提供一个有上下文关联的分组。例如,server.portserver.servlet-path属性是server组的一部分。

:不需要每个"property"都有一个"group",一些属性可以以自己的形式存在。

附录B.1.1. Group属性

groups数组包含的JSON对象可以由以下属性组成:

名称 类型 目的
name String group的全名,该属性是强制性的
type String group数据类型的类名。例如,如果group是基于一个被@ConfigurationProperties注解的类,该属性将包含该类的全限定名。如果基于一个@Bean方法,它将是该方法的返回类型。如果该类型未知,则该属性将被忽略
description String 一个简短的group描述,用于展示给用户。如果没有可用描述,该属性将被忽略。推荐使用一个简短的段落描述,第一行提供一个简洁的总结,最后一行以句号结尾
sourceType String 贡献该组的来源类名。例如,如果组基于一个被@ConfigurationProperties注解的@Bean方法,该属性将包含@Configuration类的全限定名,该类包含此方法。如果来源类型未知,则该属性将被忽略
sourceMethod String 贡献该组的方法的全名(包含括号及参数类型)。例如,被@ConfigurationProperties注解的@Bean方法名。如果源方法未知,该属性将被忽略

附录B.1.2. Property属性

properties数组中包含的JSON对象可由以下属性构成:

名称 类型 目的
name String property的全名,格式为小写虚线分割的形式(比如server.servlet-path)。该属性是强制性的
type String property数据类型的类名。例如java.lang.String。该属性可以用来指导用户他们可以输入值的类型。为了保持一致,原生类型使用它们的包装类代替,比如boolean变成了java.lang.Boolean。注意,这个类可能是个从一个字符串转换而来的复杂类型。如果类型未知则该属性会被忽略
description String 一个简短的组的描述,用于展示给用户。如果没有描述可用则该属性会被忽略。推荐使用一个简短的段落描述,开头提供一个简洁的总结,最后一行以句号结束
sourceType String 贡献property的来源类名。例如,如果property来自一个被@ConfigurationProperties注解的类,该属性将包括该类的全限定名。如果来源类型未知则该属性会被忽略
defaultValue Object 当property没有定义时使用的默认值。如果property类型是个数组则该属性也可以是个数组。如果默认值未知则该属性会被忽略
deprecated boolean 指定该property是否过期。如果该字段没有过期或该信息未知则该属性会被忽略

附录B.1.3. 可重复的元数据节点

在同一个元数据文件中出现多次相同名称的"property"和"group"对象是可以接受的。例如,Spring Boot将spring.datasource属性绑定到Hikari,Tomcat和DBCP类,并且每个都潜在的提供了重复的属性名。这些元数据的消费者需要确保他们支持这样的场景。

附录B.2. 使用注解处理器产生自己的元数据

通过使用spring-boot-configuration-processor jar, 你可以从被@ConfigurationProperties注解的节点轻松的产生自己的配置元数据文件。该jar包含一个在你的项目编译时会被调用的Java注解处理器。想要使用该处理器,你只需简单添加spring-boot-configuration-processor依赖,例如使用Maven你需要添加:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

使用Gradle时,你可以使用propdeps-plugin并指定:

dependencies {
        optional "org.springframework.boot:spring-boot-configuration-processor"
    }

    compileJava.dependsOn(processResources)
}

:你需要将compileJava.dependsOn(processResources)添加到构建中,以确保资源在代码编译之前处理。如果没有该指令,任何additional-spring-configuration-metadata.json文件都不会被处理。

该处理器会处理被@ConfigurationProperties注解的类和方法,description属性用于产生配置类字段值的Javadoc说明。

:你应该使用简单的文本来设置@ConfigurationProperties字段的Javadoc,因为在没有被添加到JSON之前它们是不被处理的。

属性是通过判断是否存在标准的getters和setters来发现的,对于集合类型有特殊处理(即使只出现一个getter)。该注解处理器也支持使用lombok的@Data, @Getter@Setter注解。

附录 B.2.1. 内嵌属性

该注解处理器自动将内部类当做内嵌属性处理。例如,下面的类:

@ConfigurationProperties(prefix="server")
public class ServerProperties {

    private String name;

    private Host host;

    // ... getter and setters

    private static class Host {

        private String ip;

        private int port;

        // ... getter and setters

    }

}

附录 B.2.2. 添加其他的元数据